package cn.tqfeiyang.smartadmin.system.service;

import cn.tqfeiyang.smartadmin.commons.pagination.QueryParams;
import cn.tqfeiyang.smartadmin.commons.toolbox.*;
import cn.tqfeiyang.smartadmin.system.entity.RoleEntity;
import cn.tqfeiyang.smartadmin.system.entity.UserEntity;
import cn.tqfeiyang.smartadmin.system.mapper.RoleMenuMapper;
import cn.tqfeiyang.smartadmin.system.mapper.UserMapper;
import cn.tqfeiyang.smartadmin.system.mapper.UserRoleMapper;
import cn.tqfeiyang.smartadmin.system.request.UserCreateDTO;
import cn.tqfeiyang.smartadmin.system.request.UserUpdateDTO;
import cn.tqfeiyang.smartadmin.system.request.UserQueryDTO;
import cn.tqfeiyang.smartadmin.system.response.RoleQueryVO;
import cn.tqfeiyang.smartadmin.system.response.UserQueryVO;
import cn.tqfeiyang.smartadmin.system.response.UserDetailVO;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.github.pagehelper.PageHelper;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import cn.tqfeiyang.smartadmin.commons.exception.BusinessException;
import cn.tqfeiyang.smartadmin.commons.pagination.PageData;

import java.util.List;
import java.util.Set;

/**
 * 用户服务
 *
 * @author tqfeiyang
 * @since 2024-08-23
 */
@Service
public class UserService {

    /**
     * 用户映射接口
     */
    @Resource
    private UserMapper userMapper;

    /**
     * 用户-角色映射接口
     */
    @Resource
    private UserRoleMapper userRoleMapper;

    /**
     * 查询用户
     *
     * @param dto 请求数据
     * @return 用户列表
     */
    public PageData<UserQueryVO> queryUsers(UserQueryDTO dto) {
        ValidationUtils.validateProperties(dto);
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        List<UserEntity> list = userMapper.selectList(dto.getWrapper());
        return PageData.create(list, UserQueryVO.class);
    }

    /**
     * 获取用户
     *
     * @param userId 用户id
     * @return 用户信息
     */
    public UserDetailVO readUser(Long userId) {
        UserEntity userEntity = checkUserExists(userId);
        return BeanUtils.map(userEntity, UserDetailVO.class);
    }

    /**
     * 添加用户
     *
     * @param dto 请求数据
     * @return 用户id
     */
    @Transactional(rollbackFor = Exception.class)
    public Long createUser(UserCreateDTO dto) {
        ValidationUtils.validateProperties(dto);
        UserEntity userEntity = BeanUtils.copy(dto, UserEntity.class);

        if (StringUtils.isNotBlank(dto.getPassword())) {
            userEntity.setSalt(RandomStringUtils.randomAlphanumeric(10));
            String encrypted = PasswordUtils.encrypt(dto.getPassword(), userEntity.getSalt());
            userEntity.setPassword(encrypted);
        }

        userMapper.insert(userEntity);
        return userEntity.getUserId();
    }

    /**
     * 修改用户
     *
     * @param userId 用户id
     * @param dto 请求数据
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(Long userId, UserUpdateDTO dto) {
        checkUserExists(userId);
        ValidationUtils.validateProperties(dto);
        UserEntity userEntity = BeanUtils.copy(dto, UserEntity.class);
        userEntity.setUserId(userId);
        userMapper.updateById(userEntity);
    }

    /**
     * 删除用户
     *
     * @param userId 用户id
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(Long userId) {
        checkUserExists(userId);
        userMapper.deleteById(userId);
        userRoleMapper.deleteRoleIdsByUserId(userId);
    }

    /**
     * 检查用户实体是否存在
     *
     * @param userId 用户id
     * @return 用户实体
     */
    protected UserEntity checkUserExists(Long userId) {
        Assert.notNull(userId, "userId不能为空");
        UserEntity userEntity = userMapper.selectById(userId);
        if (ObjectUtils.isEmpty(userEntity)) {
            throw new BusinessException("用户不存在");
        }
        return userEntity;
    }

    /**
     * 查询角色
     *
     * @param userId 用户id
     * @param dto 请求数据
     * @return 角色列表
     */
    public PageData<RoleQueryVO> queryRoles(Long userId, QueryParams dto) {
        checkUserExists(userId);
        ValidationUtils.validateProperties(dto);
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        List<RoleEntity> list = userRoleMapper.selectRoleListByUserId(userId);
        return PageData.create(list, RoleQueryVO.class);
    }

    /**
     * 更新角色
     *
     * @param userId 用户id
     * @param roleIds 角色id集合
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateRoles(Long userId, Set<Long> roleIds) {
        checkUserExists(userId);
        userRoleMapper.deleteRoleIdsByUserId(userId);
        if (CollectionUtils.isNotEmpty(roleIds)) {
            userRoleMapper.insertRoleIdsByUserId(userId, roleIds);
        }
    }

}
